import { unified } from "unified"
import parse from 'remark-parse'
import { visit } from 'unist-util-visit'


const Regex = {
    Line: /\r\n|\n/g,
    Tags: /#([dct])\s(\S+)/g,
    Subtitle: /^\[(\d{2}:\d{2}\.\d{3})(?:-(\d{2}:\d{2}\.\d{3}))?\]\s*(.*)/,
    Active:  /\[(.*?)\]\((.*?)\s(\-.*?)\)/
}

const Type = {
    P: 'paragraph',
    Tag: 'tag',
    Subtitle: 'subtitle',
    Active: 'active',
    Content: 'content'
}

const processer = unified()
    .use(parse)
    .use(() => (tree: any) => {
        visit(tree, 'text', (_node: any, _index: any, _parent: any) => {
            if (Type.P !== _parent.type) {
                return
            }
            // get value
            const str = _node.value
            // reset node
            _node.type = Type.P
            _node.value = undefined
            _node.children = []
            // split 
            const sg = str.split(Regex.Line).filter((it: any) => it)
            sg.forEach((s: any) => {
                if (Regex.Tags.test(s)) {
                    const tag = s.substring(0, 2)
                    const value = s.substring(3)
                    const custom = {
                        type: Type.Tag,
                        properties: {
                            tag: tag
                        },
                        value: value
                    }
                    _node.children.push(custom)
                }
                else if (Regex.Subtitle.test(s)) {
                    const matches = s.match(Regex.Subtitle)
                    const st = matches[1]
                    const et = matches[2]
                    const value = matches[3]

                    let type = Type.Subtitle
                    
                    let title: any
                    let options: any
                    let active: any

                    if (Regex.Active.test(value)) {
                        type = Type.Active
                        const m = value.match(Regex.Active)
                        title = m[1]
                        options = m[2]
                        active = m[3]
                    }

                    const custom = {
                        type: type,
                        properties: {
                            st: st,
                            et: et,
                            title: title,
                            options: options,
                            active: active
                        },
                        value: Type.Subtitle === type? value : ''
                    }
                    _node.children.push(custom)
                } 
            })
        })
        return tree
    })

const Parser = {
    ast: (text?:string) => {
        const _ast = processer.runSync(processer.parse(text))
        console.log('ast =>', _ast)
        return _ast;
    }
} 

export default Parser

